home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1987
/
11
/
getmem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-10-08
|
4KB
|
100 lines
/*---------------------------------------------------------------------
getmem.c
Implements low overhead memory management for nonrelocatable
blocks on the Macintosh. This code is based on "Operating System
Design: The XINU Approach" by Douglas Comer (Prentice Hall, 1984.
Great book!)
Motivation:
The Macintosh Memory Manager is designed to use relocatable
blocks (i.e. pointers to pointers) for heap data structures. In
order that relocatable blocks be free to move the Memory Manager
tries to keep nonrelocatable blocks (i.e. blocks referred to by
pointers) out of the way, i.e. in low mem. To do this, when a program
asks for a nonrelocatable block the Memory Manager starts a linear
search for available space at the bottom of the heap. In an
application such as a tree, where many thousands of small blocks are
needed, the linear search technique quickly dies.
The code below bypasses this problem by requesting one large block at
the start of execution (i.e. when init_mem is called). The function
getmem then maintains a pointer to the next available block. Thus
any request for memory is satisfied immediately. No search is needed.
The performance difference in the contour analysis is quite dramatic.
The code below is quite simple but not flexible. One notable
lack is for a routine to free memory. Such a function is shown in
Comer's book. Another limitation that only one block is used.
The functions can be extended to be able to add new blocks when it
needs additional space.
William May
303A Ridgefield Circle
Clinton, MA 01510
created: 3/25/87 very primitive version, but works:
one pool only created
user has to guess the required space
speed increase is dramatic, especially
as the contour algorithm progresses (i.e.
as the AVL tree gets quite large).
-------------------------------------------------------------------- */
#include <MemoryMgr.h>
#include "mem.h"
struct mblock memlist; /* head of free memory list */
struct pool *plist; /* head of pool list */
/*---------------------------------------------------------------------
init_mem creates a large memory pool, and initializes the necessary
data structures.
---------------------------------------------------------------------*/
int init_mem()
{
plist = (struct pool *)NewPtr(sizeof(struct pool) + DEFSIZE);
if (MemErr == noErr) {
plist->pnext = (struct pool *)0;
memlist.mnext = &(plist->firstblock);
(memlist.mnext)->mnext = (struct mblock *)0;
(memlist.mnext)->mlen = (long)(DEFSIZE);
}
return MemErr;
}
/*---------------------------------------------------------------------
getmem allocates memory in the pool. On successful completion
a pointer to the allocated space is returned to the caller. Otherwise
a null pointer (0L) is returned.
----------------------------------------------------------------------*/
int *getmem(nbytes)
unsigned long nbytes;
{
register struct mblock *p, *q, *leftover;
if (nbytes == 0) {
return (int *)0;
}
nbytes = (unsigned long)roundew(nbytes);
for (q=&memlist, p=memlist.mnext; p != 0L; q=p, p=p->mnext)
if (p->mlen == nbytes) {
q->mnext = p->mnext;
return ((int *)p);
} else if (p->mlen > nbytes) {
leftover = (struct mblock *)((unsigned long)p + nbytes);
q->mnext = leftover;
leftover->mnext = p->mnext;
leftover->mlen = (long)(p->mlen - nbytes);
return ((int *)p);
}
return ((int *)0);
}